package com.qingke.notlonely.dao;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Transaction;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;

import com.qingke.notlonely.bean.Major;
import com.qingke.notlonely.bean.School;
import com.qingke.notlonely.bean.User;
import com.qingke.notlonely.bean.UserEduction;
import com.qingke.notlonely.bean.UserInterest;
import com.qingke.notlonely.bean.UserPassword;
import com.qingke.notlonely.bean.Yue;

public class NotLonelyDAO extends NotLonelyBottomDAO{
	
	@SuppressWarnings("unchecked")
	public List<User> selectUserByAgeAndGender(int ageLow,int ageHigh,String gender){
		Criteria criteria=getCriteria(User.class);
		criteria.add(Restrictions.eq("gender", gender));
		criteria.add(Restrictions.between("age", ageLow, ageHigh));
		return criteria.list();
	}
	@SuppressWarnings("unchecked")
	public List<User> selectUserByHeight(double heightLow,double heightHigh){
		Criteria criteria=getCriteria(User.class);
		criteria.add(Restrictions.between("height", heightLow, heightHigh));
		return criteria.list();
	}
	@SuppressWarnings("unchecked")
	public List<UserInterest> selectUserInterestByGreateThanDegree(int degree){
		Criteria criteria=getCriteria(UserInterest.class);
		criteria.add(Restrictions.ge("degree", degree));
		return criteria.list();
	}
	
	public List<UserEduction> selectUserEduction(){
		return getAll(UserEduction.class);
	}
	
	public List<Yue> selectYue(){
		return getAll(Yue.class);
	}
	
	@SuppressWarnings("unchecked")
	public List<Yue> selectYueByAccepted(){
		Criteria criteria=getCriteria(Yue.class);
		criteria.add(Restrictions.eq("isAccepted", true));
		return criteria.list();
		
	}
	
	public List<?> selectUserByInviteTimes(){
		Criteria criteria=getCriteria(Yue.class);
		
		ProjectionList projList=Projections.projectionList();
		projList.add(Projections.groupProperty("inviter"));
		projList.add(Projections.rowCount(),"count");
		criteria.setProjection(projList);
		criteria.addOrder(Property.forName("count").desc());
		return criteria.list();
	}
	
	public List<?> selectUserByInviteSuccess(){
		Criteria criteria=getCriteria(Yue.class);
		
		ProjectionList projList=Projections.projectionList();
		projList.add(Projections.groupProperty("inviter"));
		projList.add(Projections.rowCount(),"count");
		criteria.setProjection(projList);
		criteria.add(Restrictions.eq("isAccepted", true));
		criteria.addOrder(Property.forName("count").desc());
		return criteria.list();
		
	}
	
	public List<?> selectUserByBeInvitedTimes(){
		Criteria criteria=getCriteria(Yue.class);
		
		ProjectionList projList=Projections.projectionList();
		projList.add(Projections.groupProperty("invitee"));
		projList.add(Projections.rowCount(),"count");
		criteria.setProjection(projList);
		criteria.addOrder(Property.forName("count").desc());
		return criteria.list();
		
	}
	
	public List<User> selectUser(){
		return getAll(User.class);
	}
	
	public User selectUserById(int id){
		return session.get(User.class, id);
	}
	
	public UserPassword selectUserPasswordById(int id){
		return session.get(UserPassword.class, id);
	}
	
	public Yue selectYueById(int id){
		return session.get(Yue.class, id);
	}
	
	public boolean isUserExistById(int id){
		User user=selectUserById(id);
		if(user==null)
			return false;
		return true;
	}
	
	public boolean isUserExistByUsername(String username){
		Map<String,Object> map=new HashMap<>();
		map.put("username", username);
		List<User> list=get(User.class,map);
		if(list.size()==0)
			return false;
		return true;
	}
	
	public boolean isYueExistById(int id){
		Yue yue=selectYueById(id);
		if(yue==null)
			return false;
		return true;
	}
	
	public boolean addUser(User user,UserPassword userPassword){
		Transaction tx=session.beginTransaction();
		try{
			session.save(user);
			DetachedCriteria detachCriteria=DetachedCriteria.forClass(User.class);
			Criteria criteria=detachCriteria.getExecutableCriteria(session);
			criteria.add(Restrictions.eq("username", user.getUsername()));
			criteria.setMaxResults(1);
			@SuppressWarnings("unchecked")
			List<User> list=criteria.list();
			user=list.get(0);
			userPassword.setId(user.getId());
			session.save(userPassword);
			tx.commit();
		}catch(HibernateException e){
			e.printStackTrace();
			tx.rollback();
			return false;
		}
		return true;
	}
	
	public School selectSchoolByName(String schoolName){
		Map<String,Object> map=new HashMap<>();
		map.put("name", schoolName);
		List<School> list=get(School.class,map);
		if(list.size()==0)
			return null;
		return list.get(0);
	}
	
	public Major selectMajorByName(String majorName){
		Map<String,Object> map=new HashMap<>();
		map.put("name", majorName);
		List<Major> list=get(Major.class,map);
		if(list.size()==0)
			return null;
		return list.get(0);
	}
}
